/**
 * Copyright 2008 Frank van Lingen Licensed under the Apache License, Version
 * 2.0 (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
 * or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package superpodder.gui;

/**
 * The main gui class. This class enables the user to configure settings, start
 * the downloads, view the help screen, etc...
 */
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Properties;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.WindowConstants;

import superpodder.controller.FeedManager;
import superpodder.model.Settings;

public class MainView extends JFrame implements ActionListener {

    private static final long serialVersionUID = 1L;

    /** Returns an ImageIcon, or null if the path was invalid. */
    protected static ImageIcon createImageIcon(String imagePath) {
        String path = System.getProperty("user.dir");
        path = path.concat(imagePath);
        System.out.println("Loading image: " + path);
        return new ImageIcon(path);
    }

    private ContentsView  contentsView = null;
    public static LogView logView      = null;
    private FeedManager   feedManager  = null;
    private JPanel        jPanel       = null;

    private SettingsView  settingsView = null;

    public MainView() {
        super("SuperPodderJ");
        System.out.println("Starting Main Viewer");
        this.setMinimumSize(new Dimension(450, 450));
        this.setResizable(true);
        this.setSize(650, 550);
        this.feedManager = new FeedManager();
        this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);

        // Enable the user to exit this application
        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent we) {
                if (MainView.this.exitConfirmed(we.getComponent(), "exit")) {
                    System.exit(0);
                }

                we.getWindow().setVisible(true);
            }

        });

        // read the feed settings
        this.readSettings();

        // build the layout of this window
        JMenuItem mi;
        final JMenuBar menuBar = new JMenuBar();
        this.setJMenuBar(menuBar);

        JMenu menu;
        menu = new JMenu("File");
        menu.add(mi = new JMenuItem("Exit"));
        mi.addActionListener(this);
        menuBar.add(menu);
        menu = new JMenu("Tools");
        menu.addActionListener(this);
        ImageIcon icon = MainView.createImageIcon("\\images\\playS.gif");
        menu.add(mi = new JMenuItem("Start", icon));
        mi.addActionListener(this);
        icon = MainView.createImageIcon("\\images\\stopS.gif");
        menu.add(mi = new JMenuItem("Stop", icon));
        mi.addActionListener(this);
        menu.add(mi = new JMenuItem("Download Size"));
        mi.addActionListener(this);
        menu.addSeparator();
        menu.add(mi = new JMenuItem("Settings"));
        mi.addActionListener(this);
        menu.add(mi = new JMenuItem("Log"));
        mi.addActionListener(this);
        menuBar.add(menu);
        menu = new JMenu("Help");
        menu.add(mi = new JMenuItem("About"));
        mi.addActionListener(this);
        menuBar.add(menu);
        menu.add(mi = new JMenuItem("Contents"));
        mi.addActionListener(this);
        menuBar.add(menu);
        menu.add(mi = new JMenuItem("Donate"));
        mi.addActionListener(this);
        menuBar.add(menu);

        // build the layout of this window
        final GridBagLayout gridbag = new GridBagLayout();

        this.jPanel = new JPanel();
        this.jPanel.setLayout(gridbag);

        // put everything in a scroll pane, as we do
        // not know how many downloads there will be
        // and how big the window will be.
        final JScrollPane scrollPane = new JScrollPane(this.jPanel,
                ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
                ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        this.add(scrollPane);

    }

    public void actionPerformed(ActionEvent evt) {
        System.out.println("Event " + evt.getActionCommand());
        if (MainView.logView == null) {
            MainView.logView = new LogView(this);
        }

        final String cmd = evt.getActionCommand();
        if (cmd.compareTo("Exit") == 0) {
            if (this.exitConfirmed(this, "exit")) {
                System.exit(0);
            }
            return;

        }
        if (cmd.compareTo("Stop") == 0) {
            if (this.exitConfirmed(this, "stop feed downloads immediately")) {
                this.feedManager.stop();
            }
            return;

        }
        if (cmd.compareTo("Download Size") == 0) {
            if (Settings.currentStatus != Settings.status.begin) {
                JOptionPane.showMessageDialog(this,
                        "Please stop or pause current downloads first");
                return;
            }
            this.jPanel.removeAll();
            this.jPanel.validate();
            Settings.currentStatus = Settings.status.start;
            final String result = this.feedManager.downloadFeeds(this.jPanel,
                    false);
            if (result.compareTo("0") != 0) {
                JOptionPane.showMessageDialog(this, "Error parsing feed file: "
                        + result);
            }
            return;
        }

        if (cmd.compareTo("About") == 0) {
            JOptionPane
                    .showMessageDialog(
                            this,
                            "SuperPodder 2010. Version 1.7. \n\nThis product includes software developed by:\n\nROME project - https://rome.dev.java.net/\nRSSLib4J project - http://freshmeat.net/projects/rsslib4j/\n\nFrank van Lingen\nhttp://vanlingen.name");
            return;
        }
        if (cmd.compareTo("Donate") == 0) {
            JOptionPane
                    .showMessageDialog(
                            this,
                            "This program is freeware, if you want to donate, \nplease donate to some of my favourite radio programs\n (or their associated stations):\n\n-This American Life (http://www.thislife.org/)\n-RadioLab (http://radiolab.org) \n-Way with Words (http://www.waywordradio.org/)");

            return;
        }
        if (cmd.compareTo("Settings") == 0) {
            if (this.settingsView == null) {
                this.settingsView = new SettingsView(this);
            }
            this.showCentered(this.settingsView);
            return;
        }
        if (cmd.compareTo("Log") == 0) {
            this.showCentered(MainView.logView);
            return;
        }
        if (cmd.compareTo("Contents") == 0) {
            if (this.contentsView == null) {
                this.contentsView = new ContentsView(this);
            }
            this.showCentered(this.contentsView);
            return;
        }
        if (cmd.compareTo("Start") == 0) {
            if (Settings.currentStatus != Settings.status.begin) {
                JOptionPane.showMessageDialog(this,
                        "Please stop or pause current downloads first");
                return;
            }

            this.jPanel.removeAll();

            this.jPanel.validate();
            Settings.currentStatus = Settings.status.start;

            final String result = this.feedManager.downloadFeeds(this.jPanel,
                    true);
            if (result.compareTo("0") != 0) {

                JOptionPane.showMessageDialog(this,
                        "Error parsing feed file. Perhaps problem with settings?: "
                                + result);
            }
            return;
        }
    }

    private boolean exitConfirmed(Component c, String action) {
        return JOptionPane.showConfirmDialog(c, "Do you really want to  "
                + action + "?", "make a choice", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION;
    }

    /**
     * Reads settings from a properties file if settings are there, if file is
     * not available it creates one.
     */
    public void readSettings() {
        // get working directory
        final String path = System.getProperty("user.dir");
        // check for the properties file.
        final String configFile = path.concat("\\SuperPodder.cfg");
        final File settings = new File(configFile);
        if (!settings.exists()) {
            try {
                settings.createNewFile();
                System.out.print("File does not exist. Creating it\n");
                final Properties properties = new Properties();
                properties.setProperty("download_dir", path + "\\Downloads");
                properties.setProperty("history", path
                        .concat("\\SuperPodder.repo"));
                properties
                        .setProperty("logs", path.concat("\\SuperPodder.log"));
                properties.setProperty("feeds", path
                        .concat("\\SuperPodder.xml"));
                properties.setProperty("threads", "2");
                properties.setProperty("torrentLink", "false");
                properties.setProperty("torrentExe",
                        "put the location of the torrent client here");
                final FileOutputStream fileIO = new FileOutputStream(settings);
                properties.store(fileIO, "Parameters");
                final String msg = new String("No config file found. Created "
                        + configFile);
                JOptionPane.showMessageDialog(this, msg);
            } catch (final Exception e) {
                final String msg = new String("Unable to create " + configFile
                        + ": " + e.getMessage());
                JOptionPane.showMessageDialog(this, msg);
            }
        }
        System.out.println("Reading settings from: " + configFile + "\n");
        try {
            final FileInputStream fileIO = new FileInputStream(configFile);
            final Properties properties = new Properties();
            properties.load(fileIO);
            Settings.downloadDir = properties.getProperty("download_dir");
            Settings.feeds = properties.getProperty("feeds");
            Settings.history = properties.getProperty("history");
            Settings.threads = new Integer(properties.getProperty("threads"));
            Settings.torrentLink = properties.getProperty("torrentLink");
            Settings.torrentExe = properties.getProperty("torrentExe");
        } catch (final Exception e) {
            final String msg = new String("Unable to create " + configFile
                    + ": " + e.getMessage());
            JOptionPane.showMessageDialog(this, msg);
        }
    }

    public void showCentered() {
        // Center frame
        final Dimension screenSize = Toolkit.getDefaultToolkit()
                .getScreenSize();
        final Dimension size = this.getSize();
        screenSize.height = screenSize.height / 2;
        screenSize.width = screenSize.width / 2;
        size.height = size.height / 2;
        size.width = size.width / 2;
        final int y = screenSize.height - size.height;
        final int x = screenSize.width - size.width;
        this.setLocation(x, y);
        this.setVisible(true);
    }

    protected void showCentered(Window window) {
        final Window parent = (Window) window.getParent();

        final Dimension dim = parent.getSize();
        final Point loc = parent.getLocationOnScreen();

        final Dimension size = window.getSize();

        loc.x += (dim.width - size.width) / 2;
        loc.y += (dim.height - size.height) / 2;

        if (loc.x < 0) {
            loc.x = 0;
        }
        if (loc.y < 0) {
            loc.y = 0;
        }

        final Dimension screen = this.getToolkit().getScreenSize();

        if (size.width > screen.width) {
            size.width = screen.width;
        }
        if (size.height > screen.height) {
            size.height = screen.height;
        }

        if (loc.x + size.width > screen.width) {
            loc.x = screen.width - size.width;
        }

        if (loc.y + size.height > screen.height) {
            loc.y = screen.height - size.height;
        }
        window.setBounds(loc.x, loc.y, size.width, size.height);
        // load the values in the text fields.
        window.setVisible(true);
    }

}
